﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace AzukiMap.Tools
{
    /// <summary>
    /// データセットヘッダ
    /// </summary>
    public struct GrdDatasetHeader { 
	    public Int16 Version;		    //バージョン = 2 
        public Int16 CoodinataeType;	//座標タイプ 1： ラジアン , 2： m（メートル） , 3： 度 
        public Int16 Projection;		//投影法 1： WGS84 
							            // 2： 日本測地系 
							            // 3： 日本測地系2000 
							            // 101 ～119： 平面直角座標系 
							            // 201 ～260： UTM 
							            // 301 ～319： 平面直角座標系2000 
        public Int16 Precision;		//データセット精度 64or32or16 
        public double MinX;			//描画領域左下X 座標 
        public double MinY;			//描画領域左下Y 座標 
        public double MinZ;			//描画領域左下Z 座標 
        public double MaxX;			//描画領域右上X 座標 
        public double MaxY;			//描画領域右上Y 座標 
        public double MaxZ;			//描画領域右上Z 座標 
        public double Scale;			//データセットスケール1:10000 なら10000 
        public byte[] Note;			//ノート [64] 終端に「\n」
    }

    /// <summary>
    /// グリッドヘッダ
    /// </summary>
    public struct GrdGridHeader {
        public double OrgX;			//グリッドの原点X座標 
        public double OrgY;			//グリッドの原点Y座標 
        public double PixelX;			//1ピクセルの幅 
        public double PixelY;			//1ピクセルの高さ 
        public Int32 W;					//横ピクセルの数（W） 
        public Int32 H;					//縦ピクセルの数（H） 
        public double Multiplier;		//グリッドﾞ値係数 
        public Int16 Resample;		//リサンプリング方式 0:内挿[補間]法, 1:最近隣法, 2:合計 
        public Int16 Transparent;		//不透明/透明設定 0:不透明, 1:透明 
        public byte[] ColorSet;		 //カラーセット名称  [76] 終端に「\n」
    }

    /// <summary>
    /// グリッドユーティリティ
    /// </summary>
    public class GrdData
    {
        private GrdDatasetHeader datasetHeader;				//データセットヘッダー部 
        private GrdGridHeader gridHeader;				//グリッドヘッダー部 
        private Int16[] datas;			//データ部 

        /// <summary>
        /// ファイルの読み込み
        /// Gridﾌｧｲﾙを読み込み、ヘッダー、データをセット
        /// </summary>
        /// <param name="br"></param>
        /// <returns></returns>
        public void Read(System.IO.BinaryReader br)
        {
            //ヘッダー部読み込み
            datasetHeader.Version = br.ReadInt16();
            datasetHeader.CoodinataeType = br.ReadInt16();
            datasetHeader.Projection = br.ReadInt16();
            datasetHeader.Precision = br.ReadInt16();
            datasetHeader.MinX = br.ReadDouble();
            datasetHeader.MinY = br.ReadDouble();
            datasetHeader.MinZ = br.ReadDouble();
            datasetHeader.MaxX = br.ReadDouble();
            datasetHeader.MaxY = br.ReadDouble();
            datasetHeader.MaxZ = br.ReadDouble();
            datasetHeader.Scale = br.ReadDouble();
            datasetHeader.Note = br.ReadBytes(64);

            gridHeader.OrgX = br.ReadDouble();
            gridHeader.OrgY = br.ReadDouble();
            gridHeader.PixelX = br.ReadDouble();
            gridHeader.PixelY = br.ReadDouble();
            gridHeader.W = br.ReadInt32();
            gridHeader.H = br.ReadInt32();
            gridHeader.Multiplier = br.ReadDouble();
            gridHeader.Resample = br.ReadInt16();
            gridHeader.Transparent = br.ReadInt16();
            gridHeader.ColorSet = br.ReadBytes(76);

            int size = gridHeader.H * gridHeader.W;
            datas = new Int16[size];
            //データ部分の読み込み
            for (int i = 0; i < size; i++)
            {
                datas[i] = br.ReadInt16();
            }

            return;
        }

        public void Write(System.IO.BinaryWriter bw)
        {
            //ヘッダー部書き込み
            bw.Write(datasetHeader.Version);
            bw.Write(datasetHeader.CoodinataeType);
            bw.Write(datasetHeader.Projection);
            bw.Write(datasetHeader.Precision);
            bw.Write(datasetHeader.MinX);
            bw.Write(datasetHeader.MinY);
            bw.Write(datasetHeader.MinZ);
            bw.Write(datasetHeader.MaxX);
            bw.Write(datasetHeader.MaxY);
            bw.Write(datasetHeader.MaxZ);
            bw.Write(datasetHeader.Scale);
            bw.Write(datasetHeader.Note);

            bw.Write(gridHeader.OrgX);
            bw.Write(gridHeader.OrgY);
            bw.Write(gridHeader.PixelX);
            bw.Write(gridHeader.PixelY);
            bw.Write(gridHeader.W);
            bw.Write(gridHeader.H);
            bw.Write(gridHeader.Multiplier);
            bw.Write(gridHeader.Resample);
            bw.Write(gridHeader.Transparent);
            bw.Write(gridHeader.ColorSet);

            int size = gridHeader.H * gridHeader.W;
            datas = new Int16[size];
            //データ部分の書き込み
            for (int i = 0; i < size; i++)
            {
                bw.Write(datas[i]);
            }

        }

        /// <summary>
        /// Gridの該当セルにデータをセット
        /// </summary>
        /// <param name="val"></param>
        /// <param name="iy"></param>
        /// <param name="ix"></param>
        private void SetData(
            double val, //(i)セットする値
            int y,		//(i)Y方向セルID
            int x		//(i)X方向セルID
            )
        {
            if (y < 0 || y >= gridHeader.H || x < 0 || x >= gridHeader.W) return;
            if (datas == null) return;
            datas[y * gridHeader.W + x] = (Int16)(val / gridHeader.Multiplier);
        }

        /// <summary>
        /// Gridの該当セルのデータを参照
        /// </summary>
        /// <param name="iy"></param>
        /// <param name="ix"></param>
        /// <returns></returns>
        private double GetData(
            int y,		//(i)Y方向セルID
            int x		//(i)X方向セルID
            )
        {
            if (y < 0 || y >= gridHeader.H || x < 0 || x >= gridHeader.W) return -999.0;
            if (datas == null) return -999.0;
            return datas[y * gridHeader.W + x] * gridHeader.Multiplier;
        }

        /// <summary>
        /// イメージブラシ作成
        /// </summary>
        /// <returns></returns>
        public ImageBrush CreateImage()
        {
            int width = gridHeader.W;
            int height = gridHeader.H;
            WriteableBitmap wb = new WriteableBitmap(width, height);
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    Color col;
                    if (datas[y * width + x] > 0)
                    {
                        col = Colors.Blue;
                    }
                    else
                    {
                        col = Colors.Yellow;
                    }
                    byte[] cp = new byte[] {col.R, col.G, col.B, col.A};
                    int pixelValue = BitConverter.ToInt32(cp, 0);
                    wb.Pixels[y * width + x] = pixelValue;
                }
            }
            ImageBrush ib = new ImageBrush();
            ib.ImageSource = wb;
            wb.Invalidate();

            return ib;
        }

    }
}
